# fucntion: 基于单文件构建一个可执行文件
# praam: filename [link_libraries...]
# example: build_target(main.cpp lib1 lib2)
# 该函数会在当前目录下生成一个可执行文件，文件名为当前目录名_文件名
# 例如：如果当前目录为 test，文件名为 main.cpp，则生成的可执行文件名为 test_main
# 如果有额外的参数，则会将其作为链接库添加到可执行文件中
function(build_target filename)
    # 获取文件除掉后缀的名称
    get_filename_component(basename ${filename} NAME_WE)
    # 获取当前目录不包含前置路径的名称
    get_filename_component(dir ${CMAKE_CURRENT_SOURCE_DIR} NAME)
    string(CONCAT target ${dir} "_" ${basename})
    # message(STATUS "Building ${filename} to ${target}")
    add_executable(${target} ${filename})
    # ARGN用来获取没有被接收处理的额外参数
    list(LENGTH ARGN arg_num)
    if(${arg_num} GREATER 0)
        # message(STATUS "Linking ${target} to ${ARGN}")
        target_link_libraries(${target} PRIVATE
            ${ARGN})
    endif()
    set_target_properties(${target} PROPERTIES
        FOLDER ${dir} # 为目标设置分组属性
    )
endfunction()

# function: 构建当前目录下的所有测试文件
# example: build_all_target lib1 lib2
# 该函数会在当前目录下查找所有的.cpp文件，并将其作为可执行文件进行编译
# 如果有额外的参数，则会将其作为链接库添加到可执行文件中
function(build_all_target)
    file(GLOB SOURCE_FILES *.cpp *.c)
    # message(STATUS "Source files: ${SOURCE_FILES} ${ARGV0}")
    foreach(file ${SOURCE_FILES})
        # ARGC用来计算函数接收的参数数量
        if(${ARGC} GREATER 0)
            # message(STATUS "ARGN ${ARGN}")
            build_target(${file} ${ARGN})
        else()
            build_target(${file})
        endif()
    endforeach()
endfunction()

function(add_valid_subdir)
    # 获取当前目录下所有文件(包含目录)相对于当前目录的相对路径
    file(GLOB subdirs RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*")
    # message(STATUS "Subdirectories: ${subdirs}")
    foreach(dir ${subdirs})
        # message(STATUS "Checking ${dir}")
        if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
            # 如果当前子目录下不包含cmake文件，则不加入cmake编译体系
            if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dir}/CMakeLists.txt")
                # message(STATUS "Adding subdirectory ${dir}")
                add_subdirectory("${dir}")
            endif()
        endif()
    endforeach()
endfunction()
